/*
 * Copyright (c) 2020 Fraunhofer FOKUS and others. All rights reserved.
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contact: mosaic@fokus.fraunhofer.de
 */

package org.eclipse.mosaic.fed.mqtt.message;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.mosaic.fed.mqtt.constants.MqttTopic;

/**
 * Mqtt Message Factory produce message
 */
public enum MqttMessageFactory {
    INSTANCE;

    public AbstractMqttMessage getMqttMessage(String topic, String message) {
        Type type = Type.fromTopic(topic);
        try {
            return (AbstractMqttMessage) type.getType().getConstructor(String.class).newInstance(message);

        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }

    public static enum Type {
        SIMPLE(MqttTopic.SIMPLE.getTopic(), SimpleMessage.class),
        VEHICLE_MOVE(MqttTopic.VEHICLE_MOVE.getTopic(), ObuMessage.class),
        MEC(MqttTopic.MEC.getTopic(), MecMessage.class);

        String topic;

        Class type;


        Type (String topic, Class type) {
            this.topic = topic;
            this.type = type;
        }

        public static Type fromTopic(String topic) {
            for (Type value : Type.values()) {
                if (value.topic.contains(MqttTopic.ALL)) {
                    String[] topics = value.topic.split(MqttTopic.ALL);
                    boolean result = Boolean.TRUE;
                    for (String t : topics) {
                        if (!StringUtils.contains(topic, t)) {
                            result = Boolean.FALSE;
                            break;
                        }
                    }

                    if (result) {
                        return value;
                    }

                } else if (StringUtils.equals(topic, value.topic)) {
                    return value;
                }
            }

            throw new RuntimeException("Can not find mqtt type for topic：" + topic + ". "
                    + "need create Type in MqttMessageFactory.class");
        }

        public Class getType() {
            return type;
        }


    }

}
